package com.higgins.eventtracking.server;

import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import com.higgins.eventtracking.client.FinanceTrackingService;
import com.higgins.eventtracking.client.SecurityAccessDeniedException;
import com.higgins.eventtracking.client.dto.ChartDataDTO;
import com.higgins.eventtracking.client.dto.DynamicTypeDTO;
import com.higgins.eventtracking.client.dto.FinanceStatsDTO;
import com.higgins.eventtracking.client.dto.TransactionDTO;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class FinanceTrackingServiceImpl extends RemoteServiceServlet implements
		FinanceTrackingService {
	
	public String insertTransaction(TransactionDTO dto) throws IllegalArgumentException	{
		DataStoreService dataStore = new DataStoreService();
		dataStore.openPersistenceManager();
		boolean success = dataStore.insertTransaction(dto);
		
		String response = "Insert was " + (success?"":"un") + "successful for "+ dto.getDescription() + " event.\n";

		dataStore.closePersistenceManager();
		return response;
	}
	public List<TransactionDTO> retrieveTransactions(Date now, Boolean weekOrMonth)		{
		FinanceTrackingDataService dataStore = new FinanceTrackingDataService();
		dataStore.openPersistenceManager();
		List<TransactionDTO> transactions = dataStore.retrieveTransactions(now, weekOrMonth);
		dataStore.closePersistenceManager();
		return transactions;
	}

	public Calendar setDateToMidday(Date date)	{
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, 12);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		return cal;
	}	
	
	double roundTwoDecimals(double d) {
        DecimalFormat twoDForm = new DecimalFormat("#.##");
        return Double.valueOf(twoDForm.format(d));
	}

	@Override
	public ChartDataDTO retrieveFinanceSavingsData(Integer points) throws IllegalArgumentException	{
		FinanceTrackingDataService dataStore = new FinanceTrackingDataService();
		dataStore.openPersistenceManager();
		
		ChartDataDTO chartData = dataStore.retrieveFinanceSavingsData(points);
		
		dataStore.closePersistenceManager();
		return chartData;
	}
	
	@Override
	public ChartDataDTO retrieveFinanceGoalsData(Integer points) throws IllegalArgumentException	{
		FinanceTrackingDataService dataStore = new FinanceTrackingDataService();
		dataStore.openPersistenceManager();
		
		ChartDataDTO chartData = dataStore.retrieveFinanceGoalsData(points);
		
		dataStore.closePersistenceManager();
		return chartData;
	}
	
	@Override
	public ChartDataDTO retrieveFinanceChartData(Boolean weeklyChart, Boolean yearlyExpense, Integer points)
			throws IllegalArgumentException {
		FinanceTrackingDataService dataStore = new FinanceTrackingDataService();
		dataStore.openPersistenceManager();
		
		ChartDataDTO chartData = dataStore.retrieveFinanceChartData(weeklyChart, yearlyExpense, points);
		
		dataStore.closePersistenceManager();
		return chartData;
	}
	@Override
	public ChartDataDTO retrieveFinanceBreakdownChartData(Boolean weeklyChart,
			Boolean yearlyExpense, Integer offset, Integer points) throws IllegalArgumentException {
		FinanceTrackingDataService dataStore = new FinanceTrackingDataService();
		dataStore.openPersistenceManager();
		
		ChartDataDTO chartData = dataStore.retrieveFinanceBreakdownChartData(weeklyChart, yearlyExpense, offset, points);
		
		dataStore.closePersistenceManager();
		return chartData;
	}
	

	@Override
	public Double retrieveTotalSpentThisWeek(Date now, Boolean yearlyExpense) throws IllegalArgumentException, SecurityAccessDeniedException {
		FinanceTrackingDataService dataStore = new FinanceTrackingDataService();
		dataStore.openPersistenceManager();
		
		Double result = dataStore.retrieveTotalSpentThisWeek(now, yearlyExpense);
		
		dataStore.closePersistenceManager();
		return result;
	}

	@Override
	public Double retrieveTotalSpentThisMonth(Date now, Boolean yearlyExpense) throws IllegalArgumentException, SecurityAccessDeniedException {
		FinanceTrackingDataService dataStore = new FinanceTrackingDataService();
		dataStore.openPersistenceManager();
		
		Double result = dataStore.retrieveTotalSpentThisMonth(now, yearlyExpense);
		
		dataStore.closePersistenceManager();
		return result;
	}

	@Override
	public Double retrieveForecastSpendThisWeek(Date now, Boolean yearlyExpense)
			throws IllegalArgumentException, SecurityAccessDeniedException {
		FinanceTrackingDataService dataStore = new FinanceTrackingDataService();
		dataStore.openPersistenceManager();
		
		Double result = dataStore.retrieveForecastSpendThisWeek(now, yearlyExpense);
		
		dataStore.closePersistenceManager();
		return result;
	}

	@Override
	public Double retrieveForecastSpendThisMonth(Date now, Boolean yearlyExpense)
			throws IllegalArgumentException, SecurityAccessDeniedException {
		FinanceTrackingDataService dataStore = new FinanceTrackingDataService();
		dataStore.openPersistenceManager();
		
		Double result = dataStore.retrieveForecastSpendThisMonth(now, yearlyExpense);
		
		dataStore.closePersistenceManager();
		return result;
	}

	@Override
	public Double retrieveAverageWeeklySpend(Date now, Boolean yearlyExpense) throws IllegalArgumentException, SecurityAccessDeniedException {
		FinanceTrackingDataService dataStore = new FinanceTrackingDataService();
		dataStore.openPersistenceManager();
		
		Double result = dataStore.retrieveAverageWeeklySpend(now, yearlyExpense);
		
		dataStore.closePersistenceManager();
		return result;
	}
	@Override
	public Double retrieveForecastSavingsThisMonth(Date now, Boolean yearlyExpense)
			throws IllegalArgumentException, SecurityAccessDeniedException {
		FinanceTrackingDataService dataStore = new FinanceTrackingDataService();
		dataStore.openPersistenceManager();
		
		Double result = dataStore.retrieveForecastSavingsThisMonth(now, yearlyExpense);
		
		dataStore.closePersistenceManager();
		return result;
	}
	@Override
	public String retrieveWeekNumber(Date now) throws IllegalArgumentException,
			SecurityAccessDeniedException {
		return DateUtility.getWeekNumberOfMonth(now).toString() + " of " + DateUtility.getWeeksInMonth(now).toString();
	}
	@Override
	public List<TransactionDTO> retrieveTransactions(Integer weekInPast,
			Boolean weekOrMonth) {
		Date date = DateUtility.addWeeks(new Date(), -weekInPast);
		return retrieveTransactions(date, weekOrMonth);
	}
	@Override
	public String updateTransaction(TransactionDTO dto)
			throws IllegalArgumentException, SecurityAccessDeniedException {
		FinanceTrackingDataService dataStore = new FinanceTrackingDataService();
		dataStore.openPersistenceManager();
		
		String returnString = dataStore.updateTransaction(dto);
		
		dataStore.closePersistenceManager();
		return returnString;
	}
	@Override
	public String deleteTransaction(Long id) throws IllegalArgumentException,
			SecurityAccessDeniedException {
		FinanceTrackingDataService dataStore = new FinanceTrackingDataService();
		dataStore.openPersistenceManager();
		
		String returnString = dataStore.deleteTransaction(id);
		
		dataStore.closePersistenceManager();
		return returnString;
	}
	@Override
	public List<DynamicTypeDTO> retrieveDynamicTypes(String category)
			throws IllegalArgumentException, SecurityAccessDeniedException {
		FinanceTrackingDataService dataStore = new FinanceTrackingDataService();
		dataStore.openPersistenceManager();
		
		List<DynamicTypeDTO> results = dataStore.retrieveDynamicTypes(category);
		
		dataStore.closePersistenceManager();
		return results;
	}
	@Override
	public String updateDynamicType(DynamicTypeDTO dto)
			throws IllegalArgumentException, SecurityAccessDeniedException {
		FinanceTrackingDataService dataStore = new FinanceTrackingDataService();
		dataStore.openPersistenceManager();
		
		String results = dataStore.updateDynamicType(dto);
		
		dataStore.closePersistenceManager();
		return results;
	}
}
